#pragma once

#include "ActivityPartition.h"

#include "ActivityEdge.h"
#include "ActivityNode.h"
#include "Element.h"

namespace uml {

const bool ActivityPartition::isDimension_default_ = false;
const bool ActivityPartition::isExternal_default_ = false;
ActivityPartition::ActivityPartition(const QString& umlType)
    : NamedElement(umlType) {}

void ActivityPartition::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    NamedElement::fromJson(json, errorList);
    ActivityGroup::fromJson(json, errorList);
    JsonSerializable::fromJsonArray(edges_, "edges", json, errorList);
    isDimension_ = json.value("isDimension").toBool(isDimension_default_);
    isExternal_ = json.value("isExternal").toBool(isExternal_default_);
    JsonSerializable::fromJsonArray(nodes_, "nodes", json, errorList);
    represents_ = JsonSerializable::create<Element>(json.value("represents"), errorList);

    JsonSerializable::fromJsonArray(subpartitions_, "subpartitions", json, errorList);
    superPartition_ = JsonSerializable::create<ActivityPartition>(json.value("superPartition"), errorList);

}

void ActivityPartition::toJson(QJsonObject& json) {
    NamedElement::toJson(json);
    ActivityGroup::toJson(json);
    JsonSerializable::toJsonArray(edges_, "edges", json);
    if (isDimension_ != isDimension_default_) {
        json.insert("isDimension", isDimension_);
    }
    if (isExternal_ != isExternal_default_) {
        json.insert("isExternal", isExternal_);
    }
    JsonSerializable::toJsonArray(nodes_, "nodes", json);
    if (represents_) {
        QJsonObject represents_json;
        represents_->toJson(represents_json);
        json.insert("represents", represents_json);
    }
    JsonSerializable::toJsonArray(subpartitions_, "subpartitions", json);
    if (superPartition_) {
        QJsonObject superPartition_json;
        superPartition_->toJson(superPartition_json);
        json.insert("superPartition", superPartition_json);
    }
}

/// <summary>
/// edges getter
/// ActivityEdges immediately contained in the ActivityPartition.
/// </summary>
vector<shared_ptr<ActivityEdge>>& ActivityPartition::edges() {
    return edges_;
}

/// <summary>
/// isDimension getter
/// Indicates whether the ActivityPartition groups other ActivityPartitions along a
/// dimension.
/// </summary>
bool ActivityPartition::isDimension() const {
    return isDimension_;
}

/// <summary>
/// isDimension setter
/// Indicates whether the ActivityPartition groups other ActivityPartitions along a
/// dimension.
/// </summary>
void ActivityPartition::setIsDimension(bool value) {
    isDimension_ = value;
}

/// <summary>
/// isExternal getter
/// Indicates whether the ActivityPartition represents an entity to which the
/// partitioning structure does not apply.
/// </summary>
bool ActivityPartition::isExternal() const {
    return isExternal_;
}

/// <summary>
/// isExternal setter
/// Indicates whether the ActivityPartition represents an entity to which the
/// partitioning structure does not apply.
/// </summary>
void ActivityPartition::setIsExternal(bool value) {
    isExternal_ = value;
}

/// <summary>
/// nodes getter
/// ActivityNodes immediately contained in the ActivityPartition.
/// </summary>
vector<shared_ptr<ActivityNode>>& ActivityPartition::nodes() {
    return nodes_;
}

/// <summary>
/// represents getter
/// An Element represented by the functionality modeled within the
/// ActivityPartition.
/// </summary>
shared_ptr<Element> ActivityPartition::represents() const {
    return represents_;
}

/// <summary>
/// represents setter
/// An Element represented by the functionality modeled within the
/// ActivityPartition.
/// </summary>
void ActivityPartition::setRepresents(shared_ptr<Element> value) {
    represents_ = value;
}

/// <summary>
/// subpartitions getter
/// Other ActivityPartitions immediately contained in this ActivityPartition (as its
/// subgroups).
/// </summary>
vector<shared_ptr<ActivityPartition>>& ActivityPartition::subpartitions() {
    return subpartitions_;
}

/// <summary>
/// superPartition getter
/// Other ActivityPartitions immediately containing this ActivityPartition (as its
/// superGroups).
/// </summary>
shared_ptr<ActivityPartition> ActivityPartition::superPartition() const {
    return superPartition_;
}

/// <summary>
/// superPartition setter
/// Other ActivityPartitions immediately containing this ActivityPartition (as its
/// superGroups).
/// </summary>
void ActivityPartition::setSuperPartition(shared_ptr<ActivityPartition> value) {
    superPartition_ = value;
}

} // namespace uml
